# Author: Chris Moyer
# OpenID specific stuff
import urllib

import marajo
from marajo.appengine.ext import db
from boto.sdb.persist import get_manager

class User(object):
    """
    User class, similar to the Google Appengine User class.
    This user object is actually a representation of the 
    OpenID Identifier that the user may have passed
    """
    _manager = None

    def __init__(self, id=None):
        """
        When passed no openid identifier, this class returns the currently logged in user,
        or raises a UserNotFoundError if none is logged in.

        When passed an openid identifier, information is gathered for the given user.
        If that user is not found, a UserNotFoundError is raised.
        """
        self.id = id
        self._auth_groups = None
        self.nickname = None
        self.email = None

    @classmethod
    def get(cls, id):
        """
        Get this user from the DB
        """
        return cls(id=id)
        

    def get_manager(self):
        if self.__class__._manager is None:
            self.__class__._manager = get_manager(domain_name = marajo.config.get("auth_domain"))
        return self.__class__._manager

    def __unicode__(self):
        return unicode(self.id)

    def __str__(self):
        return str(self.id)

    def __repr__(self):
        return "users.User(id=%s)" % self.id

    def __hash__(self):
        return hash((self.nickname, self.id, self.email))

    def __cmp__(self, other):
        return self.id == other.id

    def get_auth_groups(self):
        """
        Get the authorization groups this user is in
        """
        self._auth_groups = []
        sdb_item = self.get_manager().domain.get_item(self.id)
        if sdb_item and sdb_item.has_key("groups"):
            groups = sdb_item['groups']
            if isinstance(groups, list):
                for group in groups:
                    self._auth_groups.append(group)
            else:
                self._auth_groups.append(groups)
        return self._auth_groups
    
    def add_auth_group(self, group):
        self.get_manager().domain.put_attributes(self.id, {"groups": group}, replace=False)
        self._auth_groups = None

    def remove_auth_group(self, group):
        self.get_manager().domain.delete_attributes(self.id, {"groups": group})
        self._auth_groups = None

    def set_auth_groups(self, groups):
        """
        Set the auth groups to groups
        """
        rm_groups = self.get_auth_groups()

        for group in groups:
            if group in rm_groups:
                rm_groups.remove(group)
            else:
                self.add_auth_group(group)
        for group in rm_groups:
            self.remove_auth_group(group)
    
    def has_auth_group(self, group):
        """
        Check to make sure this user is a member of auth group "group"
        """
        return (group in self.get_auth_groups())

    def delete(self):
        """
        Delete this user
        """
        self.get_manager().domain.delete_attributes(self.id)

    @classmethod
    def list(cls):
        if cls._manager is None:
            cls._manager = get_manager(domain_name = marajo.config.get("auth_domain"))
        users = []
        for item in cls._manager.domain:
            u = User(id=item.name)
            users.append(u)
        return users


